package com.css.fxfzypg.modules.baseData.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.css.fxfzypg.base.response.RestResponse;
import com.css.fxfzypg.common.utils.BeanUtil;
import com.css.fxfzypg.common.utils.UpdateUtil;
import com.css.fxfzypg.constants.FxfzConstants;
import com.css.fxfzypg.modules.baseData.repository.BuildingVulnerabilityRepository;
import com.css.fxfzypg.modules.baseData.entity.BuildingVulnerability;
import com.css.fxfzypg.modules.baseData.service.BuildingVulnerabilityService;
import com.css.fxfzypg.modules.baseData.queryParams.BuildingVulnerabilityQueryParams;
import com.css.fxfzypg.util.*;
import com.css.fxfzypg.web.PlatformSessionContext;
import com.css.fxfzypg.zcpt.sys.entity.SUser;
import com.css.fxfzypg.zcpt.sys.service.SUserService;
import com.css.fxfzypg.zcpt.sys.service.SysAreaService;
import com.css.fxfzypg.zcpt.sys.service.SysRoleService;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.HSSFDataFormatter;
import org.apache.poi.ss.usermodel.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
@Service
public class BuildingVulnerabilityServiceImpl implements BuildingVulnerabilityService {
    @Resource
    BuildingVulnerabilityRepository buildingVulnerabilityRepository;

    @Resource
    SysRoleService sysRoleService;

    @Resource
    SUserService sUserService;

    @Resource
    SysAreaService sysAreaService;

    @Resource
    RestTemplate restTemplate;
    @Value("${basicData.url1}")
    public String basicDataUrl1;

    @Override
    public List<BuildingVulnerability> getPage(BuildingVulnerabilityQueryParams queryParams) {
        // String province = "";
        // String city = "";
        // String prefecture = "";
        // if (PlatformObjectUtils.isNotEmpty(queryParams.getProvinceId())) {
        //     province = sysAreaService.getAreaNameByAreaId(queryParams.getProvinceId());
        // }
        // if (PlatformObjectUtils.isNotEmpty(queryParams.getCityId())) {
        //     city = sysAreaService.getAreaNameByAreaId(queryParams.getCityId());
        // }
        // if (PlatformObjectUtils.isNotEmpty(queryParams.getPrefectureId())) {
        //     prefecture = sysAreaService.getAreaNameByAreaId(queryParams.getPrefectureId());
        // }
        // queryParams.setProvince(province);
        // queryParams.setCity(city);
        // queryParams.setPrefecture(prefecture);
        List<BuildingVulnerability> page = buildingVulnerabilityRepository.getPage(queryParams);
        return page;
    }

    @Override
    public Map<String, Object> getLoginPersonInfo() {
        Map<String, Object> map = new HashMap<>();
        StringBuilder str = new StringBuilder("");
        String userId = PlatformSessionContext.getUserID();
        //String userId =  "1e0348daa52647979cacb337255c3c8d";
        String user = sUserService.getSUser(userId);
        SUser sUser = CreateGson.createGson().fromJson(user, SUser.class);
        map.put("provinceId", sUser.getProvinceId());
        map.put("cityId", sUser.getCityId());
        String role = sysRoleService.getRoleByUserId(userId);
        List<Map> roleMaps = JSONObject.parseArray(role, Map.class);
        for (Map roleMap : roleMaps) {
            str.append(roleMap.get("roleCode") + ",");
        }
        String roles = str.toString();
        if (roles.contains(FxfzConstants.YPG_COUN_GL_ROLE) || roles.contains(FxfzConstants.YPG_PRI_GL_ROLE)) {
            map.put("isAdmin", true);
        } else {
            map.put("isAdmin", false);
        }
        return map;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(List<BuildingVulnerability> list) {
        String userID = PlatformSessionContext.getUserID();
        String province = sysAreaService.getAreaNameByAreaId(list.get(0).getProvinceId());
        String city = sysAreaService.getAreaNameByAreaId(list.get(0).getCityId());
        String prefecture = sysAreaService.getAreaNameByAreaId(list.get(0).getPrefectureId());
        for (BuildingVulnerability buildingVulnerability : list) {
            buildingVulnerability.setUpdateTime(new Date());
            buildingVulnerability.setUpdateUser(userID);
            buildingVulnerability.setProvince(province);
            buildingVulnerability.setCity(city);
            buildingVulnerability.setPrefecture(prefecture);
            buildingVulnerabilityRepository.update(buildingVulnerability);
        }
    }

    @Override
    public void exportExcel(HttpServletResponse response, BuildingVulnerabilityQueryParams queryParams) {
        List<BuildingVulnerability> list = buildingVulnerabilityRepository.getExportPage(queryParams);
        for (BuildingVulnerability item : list) {
            item.setStructureType(castType(item.getStructureType()));
            item.setDestroy(destroy(item.getDestroy()));
        }
        if (list == null || list.size() <= 0) {
            throw new RuntimeException("数据为空,无法导出！");
        }
        try {
            EasyPoiExcelUtil.exportExcel(list, "建筑物易损性数据信息统计", "建筑物易损性数据信息", BuildingVulnerability.class, "建筑物易损性数据信息", response);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public synchronized void save(List<BuildingVulnerability> list) {
        String userID = PlatformSessionContext.getUserID();
        String province = sysAreaService.getAreaNameByAreaId(list.get(0).getProvinceId());
        String city = sysAreaService.getAreaNameByAreaId(list.get(0).getCityId());
        String prefecture = sysAreaService.getAreaNameByAreaId(list.get(0).getPrefectureId());
        String structureType = list.get(0).getStructureType();
        // buildingVulnerabilityRepository.delAllVulnerability(province, city, prefecture, structureType);
        //查询省市县是否有这个结构的数据,并做初始化处理
        Map<String, BuildingVulnerability> initMap = initMap(province, city, prefecture, structureType);

        for (BuildingVulnerability item : list) {
            String key = province + city + prefecture + structureType + item.getDestroy();
            if (initMap.containsKey(key)) {
                UpdateUtil.copyNullProperties(initMap.get(key), item);
                item.setUpdateUser(userID);
                item.setUpdateTime(new Date());
                buildingVulnerabilityRepository.update(item);
            } else {
                item.setProvince(province);
                item.setCity(city);
                item.setPrefecture(prefecture);
                item.setCreateUser(userID);
                item.setCreateTime(new Date());
                item.setId(UUIDGenerator.getUUID());
                buildingVulnerabilityRepository.save(item);
            }
        }
    }

    @Override
    public RestResponse getBySfIntensity(String sfIntensity) {
        JSONArray jsonArray = (JSONArray) getJCSJ1(basicDataUrl1 +
                "/datacenter/jcIntensity/ypg/list?intensity=" + sfIntensity).getData();
        if (jsonArray.size() < 1) {
            return RestResponse.fail("数据管理子系统-房屋类别里,现没有设防烈度为:{}" + sfIntensity + "的数据！");
        }
        JSONObject jsonObject1 = new JSONObject();
        Map<String, List<String>> objectMap = new HashMap<>();
        List<String> list = null;
        String divinsions = "";
        //北京市-北京市-海淀区、北京市-北京市-海淀区、北京市-北京市-东城区
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject jsonObject = jsonArray.getJSONObject(i);
            String province = (String) jsonObject.get("province");
            String city = (String) jsonObject.get("city");
            String prefecture = (String) jsonObject.get("county");
            if (divinsions.contains(province + "-" + city + "-" + prefecture)) {
                continue;
            }
            divinsions = divinsions + "、" + province + "-" + city + "-" + prefecture;

            if (objectMap.containsKey(province)) {
                list = objectMap.get(province);
                // if (!("北京市".equals(city) || "天津市".equals(city) || "重庆市".equals(city) || "上海市".equals(city))) {
                //     list.add(city);
                // }
                if (!list.contains(city)) {
                    list.add(city);
                }
            } else {
                list = new ArrayList<>();
                list.add(city);
                objectMap.put(province, list);
            }
        }
        JSONArray jsonArray1 = new JSONArray();
        jsonObject1.put("divinsions", divinsions.substring(1));
        for (Map.Entry<String, List<String>> entry : objectMap.entrySet()) {
            JSONObject jsonObject2 = new JSONObject();
            jsonObject2.put("province", entry.getKey());
            jsonObject2.put("cityList", entry.getValue());
            jsonArray1.add(jsonObject2);
        }
        jsonObject1.put("provinces", jsonArray1);
        return RestResponse.succeed(jsonObject1);
    }

    @Override
    public RestResponse importVulnerability(MultipartFile file) throws IOException {
        StringBuilder msg = new StringBuilder();
        List<BuildingVulnerability> list = new ArrayList<>();
        Workbook book = WorkbookFactory.create(file.getInputStream());
        Sheet sheetAt = book.getSheetAt(0);
        for (int i = 1; i < 6; i++) {
            BigDecimal destroy0 = new BigDecimal(importByExcelForDate(sheetAt.getRow(1).getCell(i)));
            boolean numericFloatLength1 = isNumericFloatLength(destroy0);
            if (!numericFloatLength1) {
                msg.append("在第2行的第" + (i + 1) + "列的数据，请保留最多2位小数。<br/>");
            }
            BigDecimal destroy1 = new BigDecimal(importByExcelForDate(sheetAt.getRow(2).getCell(i)));
            boolean numericFloatLength2 = isNumericFloatLength(destroy1);
            if (!numericFloatLength2) {
                msg.append("在第3行的第" + (i + 1) + "列的数据，请保留最多2位小数。<br/>");
            }
            BigDecimal destroy2 = new BigDecimal(importByExcelForDate(sheetAt.getRow(3).getCell(i)));
            boolean numericFloatLength3 = isNumericFloatLength(destroy2);
            if (!numericFloatLength3) {
                msg.append("在第4行的第" + (i + 1) + "列的数据，请保留最多2位小数。<br/>");
            }
            BigDecimal destroy3 = new BigDecimal(importByExcelForDate(sheetAt.getRow(4).getCell(i)));
            boolean numericFloatLength4 = isNumericFloatLength(destroy3);
            if (!numericFloatLength4) {
                msg.append("在第5行的第" + (i + 1) + "列的数据，请保留最多2位小数。<br/>");
            }
            BigDecimal destroy4 = new BigDecimal(importByExcelForDate(sheetAt.getRow(5).getCell(i)));
            boolean numericFloatLength5 = isNumericFloatLength(destroy4);
            if (!numericFloatLength5) {
                msg.append("在第6行的第" + (i + 1) + "列的数据，请保留最多2位小数。<br/>");
            }
            if ((destroy0.add(destroy1).add(destroy2).add(destroy3).add(destroy4)).compareTo(BigDecimal.ONE) != 0) {
                msg.append("在第" + (i + 1) + "列的数据，相加不等于1。<br/>");
            }

        }
        if (msg.length() > 0) {
            return RestResponse.fail(msg.toString());
        }
        for (int i = 1; i < 6; i++) {
            BuildingVulnerability entity = new BuildingVulnerability();
            Row row = sheetAt.getRow(i);
            switch (row.getCell(0).getStringCellValue()) {
                case "基本完好":
                    entity.setDestroy("0");
                    break;
                case "轻微破坏":
                    entity.setDestroy("1");
                    break;
                case "中等破坏":
                    entity.setDestroy("2");
                    break;
                case "严重破坏":
                    entity.setDestroy("3");
                    break;
                case "毁坏":
                    entity.setDestroy("4");
                    break;
            }
            entity.setSix(new BigDecimal(importByExcelForDate(row.getCell(1))));
            entity.setSeven(new BigDecimal(importByExcelForDate(row.getCell(2))));
            entity.setEight(new BigDecimal(importByExcelForDate(row.getCell(3))));
            entity.setNine(new BigDecimal(importByExcelForDate(row.getCell(4))));
            entity.setTen(new BigDecimal(importByExcelForDate(row.getCell(5))));

            list.add(entity);
        }
        return RestResponse.succeed(list);
    }

    //判断字符串是否保留2位小数（大于等于0）
    public static boolean isNumericFloatLength(BigDecimal number) {
        String[] split = number.multiply(BigDecimal.valueOf(100)).toString().split("\\.");
        if (split.length < 2 || (new BigDecimal(split[1])).compareTo(BigDecimal.ZERO) == 0) {
            return true;
        }
        return false;
    }

    //把单元格的值转换成String
    public static String importByExcelForDate(Cell currentCell) {
        String cellValue = "";
        if (currentCell == null) {
            return null;
        }
        switch (currentCell.getCellType()) {
            case NUMERIC:
                if (DateUtil.isCellDateFormatted(currentCell)) {
                    double d = currentCell.getNumericCellValue();
                    Date date = DateUtil.getJavaDate(d);
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                    cellValue = sdf.format(date);
                    // System.out.println("=========date=" + sdf.format(date));
                } else {
                    NumberFormat nf = NumberFormat.getInstance();
                    nf.setGroupingUsed(false);//true时的格式：1,234,567,890
                    nf.setMaximumFractionDigits(8);
                    cellValue = nf.format(currentCell.getNumericCellValue());//数值类型的数据为double，所以需要转换一下
                    // System.out.println("===CELL_TYPE_NUMERIC" + cellValue);
                }
                break;
            case STRING:
                // System.out.println("===CELL_TYPE_STRING" + currentCell.getStringCellValue());
                cellValue = currentCell.getStringCellValue();
                break;
            case BOOLEAN:
                // System.out.println("====CELL_TYPE_BOOLEAN" + currentCell.getBooleanCellValue());
                cellValue = String.valueOf(currentCell.getBooleanCellValue());
                break;
            case FORMULA:
                // System.out.println("====CELL_TYPE_FORMULA" + currentCell.getCellFormula());
                cellValue = String.valueOf(currentCell.getCellFormula());
                break;
            default:
                cellValue = "";
                System.out.println("unsuported cell type");
                break;
        }
        return cellValue;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void bashSave(Map<String, Object> map) {
        String userID = PlatformSessionContext.getUserID();
        String structureType = (String) map.get("structureType");
        List<BuildingVulnerability> dataList = JSON.parseArray(JSON.toJSONString(map.get("dataList")), BuildingVulnerability.class);

        String province = null;
        Map<String, BuildingVulnerability> initMap = null;

        String[] divisionList = ((String) map.get("divisions")).split("、");
        for (String division : divisionList) {
            String[] split1 = division.split("-");
            String divisionIds = null;
            try {
                //判断省市县的名称是否符合规范
                divisionIds = sysAreaService.getIdByCondition(URLEncoder.encode(split1[0], "utf-8"),
                        URLEncoder.encode(split1[1], "utf-8"),
                        URLEncoder.encode(split1[2], "utf-8"));
            } catch (Exception e) {
                return;
            }
            String[] split = divisionIds.split("_");
            String provinceId = split[0];
            String cityId = null;
            String prefectureId = null;
            if (split.length == 2) {
                cityId = split[0];
                prefectureId = split[1];
            } else {
                cityId = split[1];
                prefectureId = split[2];
            }
            // buildingVulnerabilityRepository.delAllVulnerability(province, city, prefecture, structureType);
            //查询省是否有这个结构的数据
            //同一个省只查一次
            if (!split1[0].equals(province)) {
                initMap = initMap(split1[0], null, null, structureType);
            }

            for (BuildingVulnerability item : dataList) {
                String key = split1[0] + split1[1] + split1[2] + structureType + item.getDestroy();
                if (initMap.containsKey(key)) {
                    BuildingVulnerability buildingVulnerability = initMap.get(key);
                    buildingVulnerability.setSix(item.getSix());
                    buildingVulnerability.setSeven(item.getSeven());
                    buildingVulnerability.setEight(item.getEight());
                    buildingVulnerability.setNine(item.getNine());
                    buildingVulnerability.setTen(item.getTen());
                  //  UpdateUtil.copyNullProperties(initMap.get(key), item);
                    buildingVulnerability.setUpdateUser(userID);
                    buildingVulnerability.setUpdateTime(new Date());
                    buildingVulnerabilityRepository.update(buildingVulnerability);
                } else {
                    item.setStructureType(structureType);
                    item.setProvince(split1[0]);
                    item.setCity(split1[1]);
                    item.setPrefecture(split1[2]);
                    item.setProvinceId(provinceId);
                    item.setCityId(cityId);
                    item.setPrefectureId(prefectureId);
                    item.setCreateUser(userID);
                    item.setCreateTime(new Date());
                    item.setId(UUIDGenerator.getUUID());
                    buildingVulnerabilityRepository.save(item);
                }
            }
            province = split1[0];
        }
    }

    private Map<String, BuildingVulnerability> initMap(String province, String city, String prefecture, String structureType) {
        Map<String, BuildingVulnerability> initMap = new HashMap<>();
        List<BuildingVulnerability> list1 = buildingVulnerabilityRepository.isHaveRepeatData(province, city, prefecture,
                structureType);
        if (list1 != null && list1.size() > 0) {
            //如果有数据，同一个省市县的结构类型的破坏程度只有一条数据
            for (BuildingVulnerability v : list1) {
                initMap.put(v.getProvince() + v.getCity() + v.getPrefecture() + v.getStructureType() + v.getDestroy(), v);
            }
        }
        return initMap;
    }


    @Override
    public List<BuildingVulnerability> query(BuildingVulnerabilityQueryParams queryParams) {
        List<BuildingVulnerability> page = buildingVulnerabilityRepository.getPage(queryParams);
        // for (BuildingVulnerability item : page) {
        // String divisionIds = null;
        // try {
        //     divisionIds = sysAreaService.getIdByCondition(URLEncoder.encode(item.getProvince(), "utf-8"),
        //             URLEncoder.encode(item.getCity(), "utf-8"),
        //             URLEncoder.encode(item.getPrefecture(), "utf-8"));
        // } catch (UnsupportedEncodingException e) {
        //     e.printStackTrace();
        // }
        // String[] split = divisionIds.split("_");
        // item.setProvinceId(split[0]);
        // item.setCityId(split[1]);
        // item.setPrefectureId(split[2]);

        // }
        return page;
    }

    /**
     * 结构
     *
     * @param type
     * @return
     */
    private String castType(String type) {
        if (FxfzConstants.HIGH_STRUCTURE.equals(type)) {
            type = "高层结构";
        }
        if (FxfzConstants.STEEL_STRUCTURE.equals(type)) {
            type = "钢结构";
        }
        if (FxfzConstants.HNT_STRUCTURE.equals(type)) {
            type = "多层钢筋混凝土结构";
        }
        if (FxfzConstants.ZH_STRUCTURE.equals(type)) {
            type = "砖混结构";
        }
        if (FxfzConstants.ZM_STRUCTURE.equals(type)) {
            type = "砖木结构";
        }
        if (FxfzConstants.SOIL_STRUCTURE.equals(type)) {
            type = "土结构";
        }
        if (FxfzConstants.WOOD_STRUCTURE.equals(type)) {
            type = "木结构";
        }
        if (FxfzConstants.STONE_STRUCTURE.equals(type)) {
            type = "石结构";
        }
        if (FxfzConstants.OTHER_STRUCTURE.equals(type)) {
            type = "其他结构";
        }
        return type;
    }

    /**
     * 结构
     *
     * @param type
     * @return
     */
    private String destroy(String type) {
        if ("0".equals(type)) {
            type = "基本完好";
        }
        if ("1".equals(type)) {
            type = "轻微破坏";
        }
        if ("2".equals(type)) {
            type = "中等破坏";
        }
        if ("3".equals(type)) {
            type = "严重破坏";
        }
        if ("4".equals(type)) {
            type = "损坏";
        }
        return type;
    }

    private RestResponse getJCSJ1(String url) {
        MultiValueMap<String, Object> valueMap = new LinkedMultiValueMap<>();
        // String url = SJXTRESTURL + "/datacenter/jcRfcpY02/page?param=" + param;
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.set("Authorization", "fxfzypg");
        headers.set("subsystemCode", "fxfzypg");
        HttpEntity<MultiValueMap> r = new HttpEntity<>(valueMap, headers);
        RestResponse resp = null;
        try {
            JSONArray data = restTemplate.exchange(url, HttpMethod.GET, r, JSONObject.class).getBody().getJSONArray("data");
            resp = RestResponse.succeed(data);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return resp;
    }

    @Override
    public List<BuildingVulnerability> getVulnerability() {
        List<BuildingVulnerability> list = buildingVulnerabilityRepository.getVulnerability();
        return list;
    }

    @Override
    public List<BuildingVulnerability> getAllVulnerabilityOrder(String province, String city, String area, String tab) {
        return buildingVulnerabilityRepository.getAllVulnerability(province, city, area, tab, "");
    }

    @Override
    public List<BuildingVulnerability> remoteGetAllVulnerabilityOrder(String province, String city, String county, String tab, String source) {
        source = source.replace(",", "','");
        source = "'" + source + "'";
        return buildingVulnerabilityRepository.getAllVulnerability(province, city, county, tab, source);
    }

    /**
     * 删除易损性
     *
     * @param idList
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delbuildingVulnerability(List<String> idList) {
        buildingVulnerabilityRepository.delbuildingVulnerability(idList);
    }

    @Override
    public Integer countByCounty(String province, String city, String county) {
        return buildingVulnerabilityRepository.countByCounty(province, city, county);
    }

    @Override
    public Integer countByCity(String province, String city) {
        return buildingVulnerabilityRepository.countByCity(province, city);
    }

    @Override
    public Integer countByProvince(String name) {
        return buildingVulnerabilityRepository.countByProvince(name);
    }

    @Override
    public Integer countByProvinceAndYear(String provinceName, String taskYear) {
        return buildingVulnerabilityRepository.countByProvinceAndYear(provinceName, taskYear);
    }

    @Override
    public String getGeomByCode(String code) {
        return buildingVulnerabilityRepository.getGeomByCode(code);
    }
}
